package imper.graphic;

import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.newdawn.slick.Color;
import org.newdawn.slick.Image;
import org.newdawn.slick.SlickException;
import org.newdawn.slick.loading.LoadingList;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

public class ImageManager
{
  public final static int RESOURCE = 0;
  public final static int INDUSTRY = 1;
  public final static int CIVIL_UNIT = 2;
  public final static int ARMY_UNIT = 3;
  public final static int BOAT_UNIT = 4;
  public final static int LAND_TYPE = 5;
  public final static int FACILITIES = 6;
  public final static int ICONE = 7;

  /** Gestionnaire image */
  protected Map<Integer, Map<Integer, Image>> _image;

  /** instance */
  private static ImageManager _instance;

  /**
   * Constructor
   */
  protected ImageManager()
  {
    _image = new HashMap<Integer, Map<Integer, Image>>();
  }

  public static ImageManager getInstance()
  {
    if (_instance == null)
    {
      _instance = new ImageManager();
    }
    return _instance;
  }

  public void addImage(int pType, int pId, Image pImage)
  {
    Map<Integer, Image> imageTypeList = _image.get(pType);
    if (imageTypeList == null)
    {
      imageTypeList = new HashMap<Integer, Image>();
      _image.put(pType, imageTypeList);
    }
    imageTypeList.put(pId, pImage);
  }

  public Image getImage(int pType, int pId)
  {
    Map<Integer, Image> imageTypeList = _image.get(pType);
    if (imageTypeList != null)
    {
      return imageTypeList.get(pId);
    }
    return null;
  }

  public Integer nbImage(int pType)
  {
    Map<Integer, Image> imageTypeList = _image.get(pType);
    return imageTypeList.size();
  }

  public boolean containsImage(int pType, int pId)
  {
    Map<Integer, Image> imageTypeList = _image.get(pType);
    if (imageTypeList != null)
    {
      return imageTypeList.containsKey(pId);
    }
    return false;
  }

  public void loadImage(InputStream is, boolean deferred) throws SlickException
  {
    DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory.newInstance();
    DocumentBuilder docBuilder = null;
    try
    {
      docBuilder = docBuilderFactory.newDocumentBuilder();
    }
    catch (ParserConfigurationException e)
    {
      throw new SlickException("Could not load resources", e);
    }
    Document doc = null;
    try
    {
      doc = docBuilder.parse(is);
    }
    catch (SAXException e)
    {
      throw new SlickException("Could not load resources", e);
    }
    catch (IOException e)
    {
      throw new SlickException("Could not load resources", e);
    }

    // normalize text representation
    doc.getDocumentElement().normalize();
    NodeList listResources = doc.getElementsByTagName("image");
    int totalResources = listResources.getLength();
    if (deferred)
    {
      LoadingList.setDeferredLoading(true);
    }

    for (int resourceIdx = 0; resourceIdx < totalResources; resourceIdx++)
    {
      Node resourceNode = listResources.item(resourceIdx);
      if (resourceNode.getNodeType() == Node.ELEMENT_NODE)
      {
        // resourceNode.
        Element resourceElement = (Element)resourceNode;

        String type = resourceElement.getAttribute("type");
        String path = resourceElement.getAttribute("path");
        String trans = resourceElement.getAttribute("trans");

        Image image = null;
        if (trans != null && !"".equals(trans))
        {
          image = new Image(path, false, Image.FILTER_NEAREST, new Color(Integer.parseInt(trans, 16)));
        }
        else
        {
          image = new Image(path);
        }

        NodeList listSprites = resourceElement.getElementsByTagName("sprite");
        int totalSprites = listSprites.getLength();
        for (int spriteIdx = 0; spriteIdx < totalSprites; spriteIdx++)
        {
          Node spriteNode = listSprites.item(spriteIdx);
          if (spriteNode.getNodeType() == Node.ELEMENT_NODE)
          {
            Element spriteElement = (Element)spriteNode;
            String id = spriteElement.getAttribute("id");
            String x = spriteElement.getAttribute("x");
            String y = spriteElement.getAttribute("y");
            String height = spriteElement.getAttribute("height");
            String width = spriteElement.getAttribute("width");
            Image img = image.getSubImage(Integer.valueOf(x), Integer.valueOf(y), Integer.valueOf(width), Integer.valueOf(height));
            addImage(Integer.valueOf(type), Integer.valueOf(id), img);
          }
        }
      }
    }
  }
}
